<?php
class NICED_HttpResponse extends NICED_HttpBase
{
    protected $headers = array();
    protected $statusCode  = NULL;
    protected $content = array();
    protected $charset = "utf-8";
    protected $format  = "json";
    protected $isSendHeader  = true;
    protected static $formats = array("json", "xml", "html");

    protected static $contentTypes = array(
        "json" => "application/json",
        "xml"  => "application/xml",
        "html" => "text/html",   
    );

    public function __construct()
    {
        $this->initHandler();
        $this->getHandler()->setThrow(false);

        $this->setFormat($this->getFormat());

        parent::__construct();
    }

    public function setIsSendHeader($bool)
    {
        $this->isSendHeader = $bool;
    }
    
    public function setStatusCode($code)
    {
        $code = (int)$code;

        if (!$code || $code)
        {
            $this->handle(new NICED_Exception("status code is invalid"));
        }

        $this->statusCode = $code;
        $this->setHeader("status", self::getStatusByStatusCode($code));
    }

    public function getStatusCode()
    {
        return $this->statusCode;
    }

    public function setCharset($charset)
    {
        if (!$charset)
        {
            $this->handle(new NICED_Exception("charset is empty"));
        }

        $this->charset = $charset;
    }

    public function getCharset()
    {
        return $this->charset;
    }

    public function setContent($content)
    {
        if ($content && is_array($content))
        {
            $this->content = $content;
        }
    }

    public function getContent()
    {
        return $this->content;
    }


    public function setFormat($format)
    {
        if (!in_array($format, self::$formats))
        {
            $this->handle(new NICED_Exception("format is invalid"));
            return false;
        }
        else
        {
            $this->format = $format;
            return $this->setContentType(self::$contentTypes[$format]);
        }
    }

    public function getFormat()
    {
        return $this->format;
    }


    public function send()
    {
        if ($this->isSendHeader)
        {
            $this->sendHeaders();
        }
        $this->sendContent();
    }

    protected function sendContent()
    {
        $content = &$this->getContent();

        switch ($this->getFormat())
        {
            case 'json' : 
            {
                $content = json_encode($content);
                break;
            }
            case 'xml' :
            {
                $content = $this->buildXML($content);
                break;
            }
            case 'print_r' :
            {   
                print_r($content);
                break;
            }
            case 'var_dump' :
            {   
                var_dump($content);
                break;
            }
            case 'fs' :
            {   
                FS::pout($content);
                break;
            }
            case "html" :
            {
                break;
            }
            default :
            {
            }
        }

        echo $content;

        return true;
    }

    protected function sendHeaders()
    {
        $headers = &$this->getHeaders();

        foreach ($headers as $k => $v)
        {
            if ("Content_Type" == $k)
            {
                if ($this->charset)
                {
                    if ($v)
                    {
                        $v .= ";charset=".$this->charset;
                    }
                    else
                    {
                        $v .= "charset=".$this->charset;
                    }
                }
            }

            $k = str_replace("_", "-", $k);
            if ("STATUS" == $k)
            {
                if (is_numeric($v))
                {
                    $header = "Application-Execute-Error: ".$v;
                    //self::header_500();
                }
                else
                {
                    $header = $v;
                }
            }
            else
            {
                $header = $k.": ".$v;
            }

            header($header);
        }

        return true;
    }

    public static function header_500()
    {
        header(self::getStatusByStatusCode(500));
    }

    public static function getStatusMap()
    {
        return array ( 
            100 => "HTTP/1.1 100 Continue", 
            101 => "HTTP/1.1 101 Switching Protocols", 
            200 => "HTTP/1.1 200 OK", 
            201 => "HTTP/1.1 201 Created", 
            202 => "HTTP/1.1 202 Accepted", 
            203 => "HTTP/1.1 203 Non-Authoritative Information", 
            204 => "HTTP/1.1 204 No Content", 
            205 => "HTTP/1.1 205 Reset Content", 
            206 => "HTTP/1.1 206 Partial Content", 
            300 => "HTTP/1.1 300 Multiple Choices", 
            301 => "HTTP/1.1 301 Moved Permanently", 
            302 => "HTTP/1.1 302 Found", 
            303 => "HTTP/1.1 303 See Other", 
            304 => "HTTP/1.1 304 Not Modified", 
            305 => "HTTP/1.1 305 Use Proxy", 
            307 => "HTTP/1.1 307 Temporary Redirect", 
            400 => "HTTP/1.1 400 Bad Request", 
            401 => "HTTP/1.1 401 Unauthorized", 
            402 => "HTTP/1.1 402 Payment Required", 
            403 => "HTTP/1.1 403 Forbidden", 
            404 => "HTTP/1.1 404 Not Found", 
            405 => "HTTP/1.1 405 Method Not Allowed", 
            406 => "HTTP/1.1 406 Not Acceptable", 
            407 => "HTTP/1.1 407 Proxy Authentication Required", 
            408 => "HTTP/1.1 408 Request Time-out", 
            409 => "HTTP/1.1 409 Conflict", 
            410 => "HTTP/1.1 410 Gone", 
            411 => "HTTP/1.1 411 Length Required", 
            412 => "HTTP/1.1 412 Precondition Failed", 
            413 => "HTTP/1.1 413 Request Entity Too Large", 
            414 => "HTTP/1.1 414 Request-URI Too Large", 
            415 => "HTTP/1.1 415 Unsupported Media Type", 
            416 => "HTTP/1.1 416 Requested range not satisfiable", 
            417 => "HTTP/1.1 417 Expectation Failed", 
            500 => "HTTP/1.1 500 Internal Server Error", 
            501 => "HTTP/1.1 501 Not Implemented", 
            502 => "HTTP/1.1 502 Bad Gateway", 
            503 => "HTTP/1.1 503 Service Unavailable", 
            504 => "HTTP/1.1 504 Gateway Time-out"  
        ); 
    }

    public static function getStatusByStatusCode($code) 
    { 
        $map = self::getStatusMap();
        return isset($map[$code]) ? $map[$code] : $code; 
    }

}//end class
